using System;
using System.Collections.Generic;
using System.Text;

using Weazel.Microblaze.Simulator.Engine;

namespace Weazel.Microblaze.Simulator.Components.Microblaze.Instructions
{
    /// <summary>
    /// Load Halfword Unsigned
    /// </summary>
    public class Lhu : MemoryAccessInstruction
    {
        public override int CycleCount
        {
            get { return 1; }
        }

        public Lhu()
            : base("lhu")
        {
        }

        /// <summary>
        /// Loads a halfword (16 bits) from the halfword aligned memory location that 
        /// results from adding the contents of registers rA and rB. The data is placed 
        /// in the least significant halfword of register rD and the most significant 
        /// halfword in rD is cleared.
        /// </summary>    
        public override void Execute(MicroblazeComponent MicroblazeComponent)
        {

            uint address =
              MicroblazeComponent.ReadRegister(SourceRegisterA) +
              MicroblazeComponent.ReadRegister(SourceRegisterB);

            address &= 0xFFFFFFFE;

            ReadWordTransaction transaction = new ReadWordTransaction(MicroblazeComponent, address);
            MicroblazeComponent.BeginDataTransaction(transaction);

            while (transaction.Status != Transaction.TransactionStatus.Complete)
                MicroblazeComponent.WaitOneCycle();

            /*
            uint memory;
            MemoryAccessStatus status = MicroblazeComponent.DataMemorySpace.ReadWord(address, out memory);

            if (status == MemoryAccessStatus.Ok)
            {
                memory >>= 16;
                MicroblazeComponent.WriteRegister(DestinationRegister, memory, Address);
            }

            return status;
             * */

            // TODO: hvad sker der her?

            MicroblazeComponent.WriteRegister(DestinationRegister, transaction.Value >> 16, Address);
        }
        
        public override string ToString()
        {
            return string.Format("lhu r{0}, r{1}, r{2}",
              DestinationRegister,
              SourceRegisterA,
              SourceRegisterB
            );
        }
    }
}
